package com.example.springbootjavafx.view;

import com.example.springbootjavafx.CLibrary;
import com.example.springbootjavafx.scopes.UserDetailScope;
import com.example.springbootjavafx.service.GreetingService;
import com.example.springbootjavafx.service.TestService;
import com.example.springbootjavafx.util.SpringContextUtil;
import de.saxsys.mvvmfx.*;
import de.saxsys.mvvmfx.utils.commands.Action;
import de.saxsys.mvvmfx.utils.commands.DelegateCommand;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.scene.layout.BorderPane;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * HelloViewModel 类实现了 ViewModel 接口，用于 MVVM 架构中的视图模型部分。
 * 它提供了与视图交互的属性和方法，包括用户的姓名和问候信息。
 */
@Component
@ScopeProvider(UserDetailScope.class)
@Slf4j
public class HelloViewModel implements ViewModel {


    // 用户名属性，用于绑定到视图中的输入字段，允许用户输入他们的名字。
    @Getter
    private StringProperty name = new SimpleStringProperty();

    // 用于展示问候信息的只读属性，它根据用户输入的名字动态生成。
    @Getter
    private ReadOnlyStringWrapper message = new ReadOnlyStringWrapper();

    @Getter
    private ReadOnlyStringWrapper messageHello = new ReadOnlyStringWrapper();

//    @Getter
//    private Command sayMessageCommand;

    // 通过 Spring 自动装配 GreetingService，用于生成问候语。
    @Autowired
    private GreetingService greetingService;
    @Autowired
    private TestService testService;

    @InjectScope
    UserDetailScope userDetailScope;


    public void notifyMessage() {
        userDetailScope.publish("message","xiaozhi");//通过继Scope接口的实体类发布消息
        publish("message1","还可以");//通过ViewModel发布消息
    }



    public void sayHelloMessage() {
        messageHello.set(testService.getHello());
    }

    /**
     * 通过延迟执行，在后台线程中获取并显示动态链接库中的狗的名字。
     * 此方法使用了 DelegateCommand 来封装一个需要延迟执行的任务，这个任务会通过 JNA 调用动态链接库获取特定信息。
     * 使用了 Platform.runLater 来确保 UI 更新操作在 JavaFX 的主线程中执行。
     */
    public void sayMyMassage() {
        // 创建一个 DelegateCommand 对象，用于延迟执行一个特定的任务。
        DelegateCommand sayMessageCommand = new DelegateCommand(() -> new Action() {
            @Override
            protected void action() throws Exception {
                // 延迟 5 秒后执行下面的代码，模拟一个耗时的操作。
                Thread.sleep(5000);
                // 在 JavaFX 的主线程中更新 UI，显示从动态链接库获取的狗的名字。
                Platform.runLater(() -> {
                    messageHello.set(CLibrary.INSTANCE.hello_dog_name("jna调用动态链接库"));
                });
            }
        }, true);
        // 执行命令。
        sayMessageCommand.execute();
    }



    public void gotoList(ActionEvent actionEvent){
        // 使用FluentViewLoader加载ListView的FXML文件，并返回一个包含视图和视图模型的元组。
        ViewTuple<ListView, ListViewModel> listView = FluentViewLoader.fxmlView(ListView.class).load();
//        listView.getViewModel().initialize();//重新初始化列表页面
        // 将加载的ListView设置到主窗口的中心区域。
        BorderPane borderPane = SpringContextUtil.getBean("borderPane", BorderPane.class);
        borderPane.setCenter(listView.getView());
    }


    public void goMain(ActionEvent actionEvent){
        // 加载HelloView，并获取其视图组件。
        ViewTuple<HelloView, HelloViewModel> helloView = FluentViewLoader.fxmlView(HelloView.class).load();
        // 将加载的视图组件转换为BorderPane类型，并提取其中心部分。
        BorderPane pane = (BorderPane)helloView.getView();
        // 将提取的中心部分设置为主界面的中心部分。
        BorderPane borderPane = SpringContextUtil.getBean("borderPane", BorderPane.class);
        borderPane.setCenter(pane.getCenter());
    }

    /**
     * 初始化方法，在视图模型实例化后调用。
     * 它设置了一个监听器，以根据用户输入的名字动态更新问候信息。
     */
    public void initialize() {
        name.addListener((observable, oldValue, newValue) -> {
            if(newValue == null || newValue.trim().isEmpty()) {
                message.set("");
            } else {
                message.set(greetingService.greet(newValue));
            }
        });
    }

}
